﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Module;
using Cit.CDE.Net.Module;
using cde.SystemCommon;
using Cit.CDE.Net.Service.ModuleFactory;
using Cit.CDE.Net.Module.Commons;
using System.Text;
using System.IO;
using System.Threading;
using System.Data;
using Cit.CDE.Net.Service;

/// <summary>
/// 知识库下载
/// </summary>
public partial class main_course_DownloadLore : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string loreId = Util.objectToString(Page.Request.QueryString["LORE_ID"]);
        if (loreId != "")
        {
            cmdDownload(loreId);
            return;
        }
    }

    /// <summary>
    /// 下载文件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public void cmdDownload(string id)
    {

        //当前登陆人信息
        LoginOprator op = (LoginOprator)Session[Cit.CDE.Net.Module.Commons.CDEConstants.SESSION_LOIN_OPRATOR];
        //当前时间
        string Now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss").Replace("-", "/");

        List<CDEEntity> listEntity = new List<CDEEntity>();

        CDEEntityManager courseEm = CDEEMFactory.getEMByFullName("WEB.LORE_MANAGE");
        CDESearchCriteria courseSc = new CDESearchCriteria(courseEm);
        courseSc.addCondition("ID", id);
        List<CDEEntity> courseList = CDEService.LoadEntities(courseEm, courseSc);

        if (courseList.Count > 0)
        {
            CDEEntity m_entity = courseList[0];
            string path = System.Configuration.ConfigurationSettings.AppSettings["Lore"];
            string file = System.Web.HttpContext.Current.Server.MapPath(path + m_entity.get("LORE_ID").ToString().Trim());
            System.IO.FileInfo myfile = new System.IO.FileInfo(file);
            if (myfile.Exists)
            {
                string range = Page.Request.Headers["Range"];
                bool isResume = string.IsNullOrEmpty(range);//断点续传
                if (op != null)
                {

                    //下载记录
                    loreOperate(id, op.SysID, "0");                    
                 
                }

                try
                {

                    Page.Response.Clear();

                    bool success = ResponseFile(Page.Request, Page.Response, m_entity.get("FILE_PATH").ToString().Trim(), file, 1024000);

                    if (!success)
                    {
                        Response.Write("下载文件出错！");
                    }

                    //Page.Response.End();


                    //long fileSize = myfile.Length;
                    //Response.Clear();
                    //Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(m_entity.get("FILE_PATH").ToString().Trim()));
                    //Response.AddHeader("Content-Length", fileSize.ToString());
                    //Response.ContentType = "application/octet-stream";
                    //Response.WriteFile(file, 0, fileSize);
                    //Response.Flush();
                    //Response.Close();

                }
                catch (Exception ex)
                {
                    Response.Write("Error:" + ex.Message);
                    Util.SaveNote(ex.ToString());
                }
                finally
                {
                    Response.Close();
                }
            }
            else
            {
                showMessageErrAndOk("文件未找到，请联系管理员!");
            }
        }
    }

    /// <summary>
    /// 知识库操作
    /// </summary>
    /// <param name="id"></param>
    /// <param name="user_id"></param>
    /// <param name="type">0:下载,1:查看</param>
    /// <returns></returns>
    public bool loreOperate(string id, string user_id, string type)
    {

        //每天只记录一次
        StringBuilder sql = new StringBuilder();
//        sql.AppendFormat(@"select id from LORE_OPERATE where lore_id ={0} and user_id={1} and    oper_type={2} and
//                            dbo.DATE_FORMAT(insert_date,'YYYY/MM/DD')=dbo.DATE_FORMAT(getdate(),'YYYY/MM/DD')
//                            ", id, user_id, type);
//        DataTable op_table = Util.loadSql(sql.ToString());
//        if (op_table.Rows.Count != 0)
//        {
//            return false;
//        }

        //操作明细记录
        CDEEntityManager oper_em = CDEEMFactory.getEMByFullName("WEB.LORE_OPERATE");
        CDEEntity oper_entity = CDEEMServiceFactory.getEMService(oper_em).CreateEntity();
        oper_entity.Operation = CDEDataOperation.INSERT;
        oper_entity.set("LORE_ID", id);
        oper_entity.set("USER_ID", user_id);
        oper_entity.set("OPER_TYPE", type);
        List<CDEEntity> listEntity = new List<CDEEntity>();
        listEntity.Add(oper_entity);
        CDEService.UpdateEntities(oper_em, listEntity);
        if (listEntity[0].Result == CDEDataOperationResult.ERROR)
        {
            return false;
        }
        else
        {
            //知识库主表下载数更新
            sql=new StringBuilder();
            sql.AppendFormat(@"update LORE set DOWNLOADS=DOWNLOADS+1 where id={0}", id);
            Util.ExcSql(sql.ToString());

            return true;
        }
    }

    /// <summary>
    /// 提示信息
    /// </summary>
    /// <param name="strMsg"></param>
    protected void showMessageErrAndOk(string strMsg)
    {
        StringBuilder sbr = new StringBuilder();
        sbr.AppendFormat("<script language=\"javascript\">{0}", Environment.NewLine);
        sbr.AppendFormat("alert(\"");
        sbr.AppendFormat(strMsg);
        sbr.AppendFormat("\");</script>{0}", Environment.NewLine);
        Page.ClientScript.RegisterStartupScript(Page.GetType(), "PageStartup", sbr.ToString());

    }

    // 输出硬盘文件，提供下载
    // 输入参数 _Request: Page.Request对象，  _Response: Page.Response对象， _fileName: 下载文件名， _fullPath: 带文件名下载路径， _speed 每秒允许下载的字节数
    // 返回是否成功
    public static bool ResponseFile(HttpRequest _Request, HttpResponse _Response, string _fileName, string _fullPath, long _speed)
    {
        try
        {
            FileStream myFile = new FileStream(_fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            BinaryReader br = new BinaryReader(myFile);
            try
            {
                _Response.AddHeader("Accept-Ranges", "bytes");
                _Response.Buffer = false;
                long fileLength = myFile.Length;
                long startBytes = 0;

               
                int pack = 10240; //10K bytes
                //int sleep = 200;   //每秒5次   即5*10K bytes每秒
                double s = 1000 * pack / _speed;
                int sleep = (int)Math.Floor(s) + 1;
                if (_Request.Headers["Range"] != null)
                {
                    _Response.StatusCode = 206;
                    string[] range = _Request.Headers["Range"].Split(new char[] { '=', '-' });
                    startBytes = Convert.ToInt64(range[1]);
                }
                _Response.AddHeader("Content-Length", (fileLength - startBytes).ToString());
                if (startBytes != 0)
                {
                    _Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength));
                }
                _Response.AddHeader("Connection", "Keep-Alive");
                _Response.ContentType = "application/octet-stream";
                _Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(_fileName, System.Text.Encoding.UTF8));

                br.BaseStream.Seek(startBytes, SeekOrigin.Begin);
                double d = (fileLength - startBytes) / pack;
                int maxCount = (int)Math.Floor(d) + 1;
                for (int i = 0; i < maxCount; i++)
                {
                    if (_Response.IsClientConnected)
                    {
                        _Response.BinaryWrite(br.ReadBytes(pack));
                        Thread.Sleep(sleep);
                    }
                    else
                    {
                        i = maxCount;
                    }
                }
            }
            catch
            {
                return false;
            }
            finally
            {
                br.Close();
                myFile.Close();
            }
        }
        catch
        {
            return false;
        }
        return true;
    }


}
